using System;
using System.Collections.Generic;
using System.IO;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using ExcelTemplateEngine.Tests.Helpers;

namespace ExcelTemplateEngine.Tests.Infrastructure
{
    /// <summary>
    /// 集成测试基类 - 为集成测试提供Excel文件操作和验证功能
    /// </summary>
    public abstract class IntegrationTestBase : TestBase
    {
        /// <summary>
        /// 创建空白的Excel工作簿
        /// </summary>
        protected SpreadsheetDocument CreateBlankWorkbook(string filePath)
        {
            return MeasurePerformance("CreateBlankWorkbook", () =>
            {
                var document = SpreadsheetDocument.Create(filePath, DocumentFormat.OpenXml.SpreadsheetDocumentType.Workbook);
                
                // 创建工作簿部分
                var workbookPart = document.AddWorkbookPart();
                workbookPart.Workbook = new Workbook();
                
                // 创建工作表部分
                var worksheetPart = workbookPart.AddNewPart<WorksheetPart>();
                worksheetPart.Worksheet = new Worksheet(new SheetData());
                
                // 创建工作表定义
                var sheets = workbookPart.Workbook.AppendChild(new Sheets());
                var sheet = new Sheet()
                {
                    Id = workbookPart.GetIdOfPart(worksheetPart),
                    SheetId = 1,
                    Name = "Sheet1"
                };
                sheets.Append(sheet);
                
                workbookPart.Workbook.Save();
                
                Logger.LogDebug("Created blank workbook: {FilePath}", filePath);
                return document;
            });
        }
        
        /// <summary>
        /// 创建包含模板的Excel工作簿
        /// </summary>
        protected SpreadsheetDocument CreateTemplateWorkbook(string filePath, Dictionary<string, string> cellTemplates)
        {
            return MeasurePerformance("CreateTemplateWorkbook", () =>
            {
                var document = CreateBlankWorkbook(filePath);
                
                try
                {
                    var workbookPart = document.WorkbookPart!;
                    var worksheetPart = workbookPart.WorksheetParts.First();
                    var worksheet = worksheetPart.Worksheet;
                    var sheetData = worksheet.GetFirstChild<SheetData>()!;
                    
                    foreach (var template in cellTemplates)
                    {
                        var cellAddress = template.Key;
                        var templateText = template.Value;
                        
                        var cell = CreateCell(cellAddress, templateText);
                        AddCellToWorksheet(sheetData, cell);
                    }
                    
                    worksheet.Save();
                    Logger.LogDebug("Created template workbook with {Count} templates", cellTemplates.Count);
                    
                    return document;
                }
                catch
                {
                    document.Dispose();
                    throw;
                }
            });
        }
        
        /// <summary>
        /// 创建单元格
        /// </summary>
        private Cell CreateCell(string cellReference, string value)
        {
            var cell = new Cell()
            {
                CellReference = cellReference,
                DataType = CellValues.InlineString
            };
            
            var inlineString = new InlineString();
            inlineString.AppendChild(new DocumentFormat.OpenXml.Spreadsheet.Text(value));
            cell.AppendChild(inlineString);
            
            return cell;
        }
        
        /// <summary>
        /// 将单元格添加到工作表
        /// </summary>
        private void AddCellToWorksheet(SheetData sheetData, Cell cell)
        {
            var cellReference = cell.CellReference!.Value!;
            var rowIndex = GetRowIndex(cellReference);
            
            // 查找或创建行
            var row = sheetData.Elements<Row>().FirstOrDefault(r => r.RowIndex?.Value == (uint)rowIndex);
            if (row == null)
            {
                row = new Row() { RowIndex = (uint)rowIndex };
                
                // 按顺序插入行
                var nextRow = sheetData.Elements<Row>().FirstOrDefault(r => r.RowIndex?.Value > (uint)rowIndex);
                if (nextRow != null)
                {
                    sheetData.InsertBefore(row, nextRow);
                }
                else
                {
                    sheetData.AppendChild(row);
                }
            }
            
            // 按顺序插入单元格
            var columnIndex = GetColumnIndex(cellReference);
            var nextCell = row.Elements<Cell>().FirstOrDefault(c => GetColumnIndex(c.CellReference!.Value!) > columnIndex);
            if (nextCell != null)
            {
                row.InsertBefore(cell, nextCell);
            }
            else
            {
                row.AppendChild(cell);
            }
        }
        
        /// <summary>
        /// 从单元格引用获取行索引
        /// </summary>
        private int GetRowIndex(string cellReference)
        {
            var rowPart = new string(cellReference.Where(char.IsDigit).ToArray());
            return int.Parse(rowPart);
        }
        
        /// <summary>
        /// 从单元格引用获取列索引
        /// </summary>
        private int GetColumnIndex(string cellReference)
        {
            var columnPart = new string(cellReference.Where(char.IsLetter).ToArray());
            int result = 0;
            
            for (int i = 0; i < columnPart.Length; i++)
            {
                result = result * 26 + (columnPart[i] - 'A' + 1);
            }
            
            return result;
        }
        
        /// <summary>
        /// 验证Excel文件的结构
        /// </summary>
        protected void AssertExcelStructure(string filePath, int expectedSheetCount = 1, int? expectedRowCount = null, int? expectedCellCount = null)
        {
            AssertFileExists(filePath, minSize: 1000); // Excel文件至少应该有1KB
            
            MeasurePerformance("AssertExcelStructure", () =>
            {
                using var document = SpreadsheetDocument.Open(filePath, false);
                var workbookPart = document.WorkbookPart!;
                
                // 验证工作表数量
                var sheets = workbookPart.Workbook.Sheets!.Elements<Sheet>();
                Assert.Equal(expectedSheetCount, sheets.Count());
                
                if (expectedRowCount.HasValue || expectedCellCount.HasValue)
                {
                    var firstWorksheetPart = workbookPart.WorksheetParts.First();
                    var sheetData = firstWorksheetPart.Worksheet.GetFirstChild<SheetData>()!;
                    
                    if (expectedRowCount.HasValue)
                    {
                        var rowCount = sheetData.Elements<Row>().Count();
                        Assert.Equal(expectedRowCount.Value, rowCount);
                    }
                    
                    if (expectedCellCount.HasValue)
                    {
                        var cellCount = sheetData.Elements<Row>().SelectMany(r => r.Elements<Cell>()).Count();
                        Assert.Equal(expectedCellCount.Value, cellCount);
                    }
                }
                
                Logger.LogDebug("Excel structure validation passed for {FilePath}", filePath);
            });
        }
        
        /// <summary>
        /// 读取Excel文件中的单元格值
        /// </summary>
        protected string? ReadCellValue(string filePath, string cellReference, string sheetName = "Sheet1")
        {
            return MeasurePerformance("ReadCellValue", () =>
            {
                using var document = SpreadsheetDocument.Open(filePath, false);
                var workbookPart = document.WorkbookPart!;
                
                // 查找工作表
                var sheet = workbookPart.Workbook.Descendants<Sheet>().FirstOrDefault(s => s.Name == sheetName);
                if (sheet == null)
                    return null;
                
                var worksheetPart = (WorksheetPart)workbookPart.GetPartById(sheet.Id!);
                var cell = worksheetPart.Worksheet.Descendants<Cell>().FirstOrDefault(c => c.CellReference == cellReference);
                
                if (cell == null)
                    return null;
                
                // 处理不同的数据类型
                if (cell.DataType != null && cell.DataType.Value == CellValues.SharedString)
                {
                    var sharedStringTablePart = workbookPart.GetPartsOfType<SharedStringTablePart>().FirstOrDefault();
                    if (sharedStringTablePart != null)
                    {
                        var sharedStringTable = sharedStringTablePart.SharedStringTable;
                        var index = int.Parse(cell.CellValue!.Text);
                        return sharedStringTable.ElementAt(index).InnerText;
                    }
                }
                else if (cell.DataType != null && cell.DataType.Value == CellValues.InlineString)
                {
                    return cell.InlineString?.Text?.Text;
                }
                
                return cell.CellValue?.Text;
            });
        }
        
        /// <summary>
        /// 验证Excel文件中的单元格值
        /// </summary>
        protected void AssertCellValue(string filePath, string cellReference, string expectedValue, string sheetName = "Sheet1")
        {
            var actualValue = ReadCellValue(filePath, cellReference, sheetName);
            Assert.Equal(expectedValue, actualValue);
        }
        
        /// <summary>
        /// 验证Excel文件中的多个单元格值
        /// </summary>
        protected void AssertCellValues(string filePath, Dictionary<string, string> expectedValues, string sheetName = "Sheet1")
        {
            foreach (var expected in expectedValues)
            {
                AssertCellValue(filePath, expected.Key, expected.Value, sheetName);
            }
        }
        
        /// <summary>
        /// 创建简单的测试数据模板
        /// </summary>
        protected Dictionary<string, string> CreateSimpleTemplate()
        {
            return new Dictionary<string, string>
            {
                ["A1"] = "姓名",
                ["B1"] = "年龄",
                ["A2"] = "{{ds.Name}}",
                ["B2"] = "{{ds.Age}}"
            };
        }
        
        /// <summary>
        /// 创建列表扩展模板
        /// </summary>
        protected Dictionary<string, string> CreateListTemplate()
        {
            return new Dictionary<string, string>
            {
                ["A1"] = "员工列表",
                ["A2"] = "姓名",
                ["B2"] = "部门",
                ["C2"] = "薪资",
                ["A3"] = "{{employees.Name}}",
                ["B3"] = "{{employees.Department}}",
                ["C3"] = "{{employees.Salary}}"
            };
        }
    }
}